<?php
namespace App\Libs\Common;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

/**
 *   接收通知控制器
 */
class JdAuthController extends Controller
{	
	
		  //商户ID
	    public $merchantCode = "33654861";

		//DES的密钥
		public $des_key = "s8h7u6i5";

		//白条公钥
		public $public_pfile = "./Public/JD_RSA/public_xb.pem";

		//商户公钥
		public $public_file  = "./Public/JD_RSA/public_ly.pem";

		//商户私钥
		public $private_file = "./Public/JD_RSA/private_ly.pem";


		public function test()
		{

			//https://opencredit.jd.com/oauth2/bind?merchantCode=33654861
		}


		/*
		*    解绑授权(取消授权)
		*/
		public function unbind($openId)
		{
			header("Content-type: text/html; charset=utf-8");

			//$openId=I('openId','b1de038c1e367326e32a576879b2733d');

			$Util=A('Util/RsaUtil');

			//业务测试数据,json格式
			$data = '{"openId":"'.$openId.'"}';
			//DES加密
			$reqData = $Util->des_encrypt($data,$this->des_key);

			$reqData = $reqData.",".base64_encode($this->des_key);
			
			//RSA加密
			$reqData 	 = $this->rsa_encrypt($reqData,$this->public_pfile);

			//RSA签名
			$reqData 	 = $this->rsa_sign($reqData,$this->private_file);

			//拼装参数
			$sign    = urlencode($reqData);

			$submitData = array(
				'merchantCode'	=>	$this->merchantCode,
				'data'		=>	$sign
			);

			//提交数据
			$rows = $this->postData(array(
				'url'		=>	'https://opencredit.jd.com/oauth2/unbind',
				'data'	=>	$submitData,
			));

			if ($rows['isSuccess']) 
			{
				return true;

			}else{
				return false;
			}


		}
	
		//授权回调
		public function callback()
		{
			header("Content-type: text/html; charset=utf-8");
			
			$accessToken=I('accessToken','a0bb103131');
			
			$Util=A('Util/RsaUtil');

			//业务测试数据,json格式
			$data = '{"accessToken":"'.$accessToken.'"}';
			//DES加密
			$reqData = $Util->des_encrypt($data,$this->des_key);

			$reqData = $reqData.",".base64_encode($this->des_key);
			
			//RSA加密
			$reqData 	 = $this->rsa_encrypt($reqData,$this->public_pfile);

			//RSA签名
			$reqData 	 = $this->rsa_sign($reqData,$this->private_file);


			//拼装参数
			$sign    = urlencode($reqData);

			$submitData = array(
				'merchantCode'	=>	$this->merchantCode,
				'data'		=>	$sign
			);

			//提交数据
			$rows = $this->postData(array(
				'url'		=>	'https://opencredit.jd.com/access/rights',
				'data'	=>	$submitData,
			));
			
			if($rows["responseCode"]=="000000")
			{
				$data = $rows["data"];
				$data = urldecode($data);
				$str = explode(",",$data);//通过,拆解字符串
				//RSA验签
				$verify = $this->verify($str[0],$str[1],$this->public_pfile);
 
				if($verify!="1")  exit("RSA验签失败");
				
				$data = $str[0];
				//RSA解密
				$data = $this->rsa_design($data,$this->private_file);
				
				if($data==""){ echo "RSA解密失败";return; }
				//DES解密
				$str = explode(",",$data);//通过,拆解字符串
				$reqData = $Util->des_decrypt($str[0],base64_decode($str[1]));
				$info = json_decode($reqData,true);

				$arr=$this->returnResponse($info);

				$ApiJd=A('ApiJd/Auth');

				$ApiJd->index($arr);

			}else{
				echo $rows["responseMessage"];	//错误
				return;

			}
					
		}

		private function returnResponse($info)
		{

			$arr=array();

			//授权状态1已授权 0 已解除授权
			if ($info['accessStatus']) 
			{
				$arr['openId']=$info['openId'];
				//信用分
				$arr['zm_score']=$info['101'];
				//信用等级
				$arr['credit_level']=$info['102'];

				$arr['create_time']=$info['108'];

				$arr['name']=$info['204'];

				$arr['phone']=$info['205'];
			}

			return $arr;
		}

		/**
		 * 普通CRUL的方法:post,get
		 * @param array $_param
		 * url = 访问的地址
		 * data = 提交的数据
		 * type = 提交模式:GET,POST
		 * header = 头协议
		 * @return array|bool|json
		 */
		public function postData($_param=array()){
				$url	= isset($_param['url']) ? $_param['url'] : '';
				$data = isset($_param['data']) ? $_param['data'] : array();
				$type = isset($_param['type']) ? $_param['type'] : 'POST';
				$header = isset($_param['header']) ? $_param['header'] : null;
				$ch = curl_init();
				curl_setopt($ch, CURLOPT_URL, $url);
				if($header) {
						curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
				}
				curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $type);
				curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
				curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
				curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36');
				curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
				curl_setopt($ch, CURLOPT_TIMEOUT, 15);
				curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
				if($type=='POST'){
						curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//数据
				}
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
				$body = curl_exec($ch);
				curl_close($ch);

				return self::json($body);
		}



		/**
		 * 对json进行编码或解码
		 * @param null $data
		 * @param int $DataType
		 * @return bool | array | json
		 */
		public function json($data=null,$DataType=1)
		{
				if($data){
						if(is_array($data)){
								header('Content-type:application/json');
								return json_encode($data);
						}else{
								return json_decode($data,$DataType);
						}
				}
		}


		/**
	     * RSA签名
	     * @param $content
	     * @param $rsaPrivateKeyPem
	     * @return string
	     */
	    public function rsa_sign($data,$private_file) {
					if (empty($data))
					{
							return false;
					}
	        if(file_exists($private_file))
	        {
	            $pricode = file_get_contents($private_file);
	        }else{
	            exit('不能使用private文件不存在');
	        }
	        $priKey = openssl_pkey_get_private($pricode);
	        if(!$priKey){
	            exit('不能使用private.pem');
	        }
	        $res = openssl_get_privatekey($priKey);
	        openssl_sign($data, $sign, $res, OPENSSL_ALGO_MD5);
	        openssl_free_key($res);
	        $sign = $data.",".base64_encode($sign);
	        return $sign;
	    }

	    /**
	     * RSA解密
	     * @param $content
	     * @param $rsaPrivateKeyPem
	     * @return string
	     */
		 public function rsa_design($data,$private_file) 
		 {

				 if (empty($data))
				 {
						 return false;
				 }
				 //$data = base64_decode($data);
				 if(file_exists($private_file))
				 {
						 $pricode = file_get_contents($private_file);
				 }else{
						 exit('不能使用private文件不存在');
				 }
				 $pkeyid = openssl_pkey_get_private($pricode);
				 if(!$pkeyid){
						 exit('不能使用private.pem');
				 }
				$split = str_split(base64_decode($data), 128);// 1024bit  固定172
				$decode_data = "";
				foreach ($split AS $part) {
					 $isOkay = openssl_private_decrypt($part, $de_data, $pkeyid);// base64_decode($part) base64在这里使用，因为172字节是一组，是encode来的
					 $decode_data.= $de_data;
					 if(!$isOkay){
						 	echo "解密分解解析错误";
						 	return false;
					 }
				}
				return $decode_data;
		 }

		/**
		*  RSA加密
		* 利用约定数据和秘钥生成数字签名
		* @param $data 待加密数据
		* @return String 返回数据base64_encode
		*/
		public function rsa_encrypt($data='',$public_pfile)
		{
				if (empty($data)) return false;
		
		        if(file_exists($public_pfile))
		        {
		            $pricode = file_get_contents($public_pfile);
		        }else{
		            exit('不能使用public文件不存在');
		        }

				$priKey =  openssl_pkey_get_public($pricode);

				if (!$priKey)
				{
						echo "Public key resource identifier False!";
						return false;
				}

				openssl_public_encrypt($data,$encrypted,$priKey);
				// 加密后的内容通常含有特殊字符，需要编码转换下，在网络间通过url传输时要注意base64编码是否是url安全的
				$encrypted = base64_encode($encrypted);
				return $encrypted;
		}

		/**
		 * 利用公钥和数字签名以及约定数据验证合法性
		 * @param $data 待验证数据
		 * @param $signature 数字签名
		 * @return -1:error验证错误 1:correct验证成功 0:incorrect验证失败
		 */
		public function rsa_decrypt($data='',$public_file)
		{
				if (empty($data))
				{
						return false;
				}
				// echo $data;exit;
				$data = base64_decode($data);
				if(file_exists($public_file)){
						$public_key = file_get_contents($public_file);
				}
				if (empty($public_key))
				{
						echo "Public Key error!";
						return false;
				}
				$pkeyid = openssl_pkey_get_public($public_key);
				if (empty($pkeyid))
				{
						echo "public key resource identifier False!";
						return false;
				}
				$decrypted = "";
				openssl_public_decrypt($data,$decrypted,$pkeyid,OPENSSL_ALGO_MD5);//公钥解密
				//$decrypted = base64_encode($decrypted);//加密后的内容通常含有特殊字符，需要编码转换下，在网络间通过url传输时要注意base64编码是否是url安全的
				return $decrypted;
		}


	    // RSA验签
	    public function verify($data, $sign, $publicRsaPath)  
	    {
	        //读取公钥文件
	        $pubKey = file_get_contents($publicRsaPath);
	        //转换为openssl格式密钥
	        $res = openssl_get_publickey($pubKey);
	        //调用openssl内置方法验签，返回bool值
	        $result = (bool) openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_MD5);
	        //释放资源
	        openssl_free_key($res);
	        //返回资源是否成功
	        return $result;
	    }








		
	
}